﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using MySQL.Db;

namespace Gollie
{
	public class VendorInfo
	{
		public uint Id;
		public string BedrijfsNaam;
		public string Straat;
		public string Postcode;
		public string Plaats;
		public string Land;
		public string Website;
		public string KvkNummer;
		public string FactuurNaam;
		public string FactuurLand;
		public string FactuurRekeningnummer;
		public int Branche;
		public bool AllowRefund;

		private string bufferedLogoPath = null;

		internal VendorInfo(uint id)
		{
			this.Id = id;
		}

		internal VendorInfo(ResultSet resultSet)
			: this(resultSet, 0)
		{ }

		internal VendorInfo(ResultSet resultSet, int row)
		{
			int o;

			this.Id = resultSet.GetUInt32(row, "vid");
			this.BedrijfsNaam = resultSet.GetString(row, "name") ?? "";
			this.Straat = resultSet.GetString(row, "street") ?? "";
			this.Postcode = resultSet.GetString(row, "zipcode") ?? "";
			this.Plaats = resultSet.GetString(row, "city") ?? "";
			this.Land = resultSet.GetString(row, "country") ?? "";
			this.Website = resultSet.GetString(row, "website") ?? "";
			this.KvkNummer = resultSet.GetString(row, "kvknummer") ?? "";
			this.FactuurNaam = resultSet.GetString(row, "billingname") ?? "";
			this.FactuurLand = resultSet.GetString(row, "billingcountry") ?? "";
			this.FactuurRekeningnummer = resultSet.GetString(row, "billingaccount") ?? "";
			this.AllowRefund = resultSet.GetBool(row, "allowrefund");

			o = resultSet.GetInt32(row, "branche");
			this.Branche = (o == Int32.MinValue ? 0 : o);

		}

		internal static VendorInfo GetVendorInfo(uint vendorId)
		{
			return Database.Queries.GetVendor(vendorId);
		}

		internal string LogoNumber
		{
			get
			{
				if (this.Id <= 1)
					return null;

				return this.Id.ToString("00000000");
			}
		}

		internal string LogoFilePattern
		{
			get
			{
				if (this.Id <= 1)
					return null;

				return this.LogoNumber + ".*";
			}
		}

		internal string LogoPath
		{
			get
			{
				if (this.Id <= 1)
					return null;

				if (this.bufferedLogoPath == null)
				{
					string folder = System.IO.Path.Combine(ConfigAppSettings.GetValue("VendorLogoFolder"));

					string[] files = System.IO.Directory.GetFiles(folder, this.LogoFilePattern);
					if (files.Length == 0)
						this.bufferedLogoPath = "";
					else
						this.bufferedLogoPath = files[0];
				}
				return this.bufferedLogoPath;
			}
		}

		internal string LogoMediumPath
		{
			get
			{
				if (string.IsNullOrEmpty(this.LogoPath))
					return null;

				string mediumPath = Path.Combine(Path.GetDirectoryName(this.LogoPath), Path.GetFileNameWithoutExtension(this.LogoPath));
				mediumPath = mediumPath + "_medium" + Path.GetExtension(this.LogoPath);

				this.CreateResizedLogo(mediumPath, new Size(200, 100));

				return mediumPath;
			}

		}

		internal string LogoSmallPath
		{
			get
			{
				if (string.IsNullOrEmpty(this.LogoPath))
					return null;

				string smallPath = Path.Combine(Path.GetDirectoryName(this.LogoPath), Path.GetFileNameWithoutExtension(this.LogoPath));
				smallPath = smallPath + "_small" + Path.GetExtension(this.LogoPath);

				this.CreateResizedLogo(smallPath, new Size(117, 30));

				return smallPath;
			}
		}

		internal string LogoXXSmallPath
		{
			get
			{
				if (string.IsNullOrEmpty(this.LogoPath))
					return null;

				string smallPath = Path.Combine(Path.GetDirectoryName(this.LogoPath), Path.GetFileNameWithoutExtension(this.LogoPath));
				smallPath = smallPath + "_XXsmall" + Path.GetExtension(this.LogoPath);

				this.CreateResizedLogo(smallPath, new Size(58, 15));

				return smallPath;
			}
		}

		private void CreateResizedLogo(string resizedPath, Size maxSize)
		{
			if (File.Exists(resizedPath) == false)
			{
				using (Image img = Image.FromFile(this.LogoPath))
				{
					if (img.Width <= maxSize.Width && img.Height <= maxSize.Height)
					{
						File.Copy(this.LogoPath, resizedPath);
					}
					else
					{
						Size newSize = Calculator.ResizeWithRatio(img.Size, maxSize);
						using (Bitmap cpy = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppArgb))
						{
							using (Graphics gr = Graphics.FromImage(cpy))
							{
								gr.Clear(Color.Transparent);

								// This is said to give best quality when resizing images
								gr.InterpolationMode = InterpolationMode.HighQualityBicubic;

								Point leftTop = new Point(0, 0);
								gr.DrawImage(img,
									new Rectangle(leftTop, newSize),
									new Rectangle(leftTop, img.Size),
									GraphicsUnit.Pixel);
							}

							cpy.Save(resizedPath);
						}
					}
				}
			}
		}

		internal static void ValidateName(string arg)
		{
			if (arg.Length < 2 || arg.Length > 96)
				throw new ArgumentException("Bedrijfsnaam is minimaaal 2 en maximaal 96 posities lang");
		}

		internal static void ValidateAddress(string arg)
		{
			if (arg.Length < 3 || arg.Length > 64)
				throw new ArgumentException("Adres is minimaaal 3 en maximaal 64 posities lang");
		}

		internal static string ValidateZipcode(string arg)
		{
			if (System.Text.RegularExpressions.Regex.IsMatch(arg, "^\\d{4} ?[a-zA-Z]{2}$") == false)
				throw new ArgumentException("Postcode ongeldig");

			return arg.Substring(0, 4) + " " + arg.Substring(arg.Length - 2, 2).ToUpper();
		}

		internal static string ValidateIBAN(string arg)
		{
			string newNum = Calculator.VerifyAccountNumber(arg);
			if (newNum == null)
				throw new ArgumentException("IBAN ongeldig");

			return newNum;
		}

		internal static string ValidateURL(string arg)
		{
			if (System.Text.RegularExpressions.Regex.IsMatch(arg, "^(((http|https):\\/\\/)?www\\..+\\.[A-Za-z]{2,10})?$") == false)
				throw new ArgumentException("Website ongeldig");

			if (arg.StartsWith("http") == false)
				arg = "http://" + arg;

			return arg;
		}
	}
}